package com.zw.yzk.kabu.domain.repository;


import com.zw.yzk.kabu.domain.executor.ExecutionThread;
import com.zw.yzk.kabu.domain.executor.ThreadExecutor;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action0;
import rx.schedulers.Schedulers;
import rx.subscriptions.Subscriptions;

abstract public class UseCase {

    private byte[] classNameByte = new byte[]{97, 110, 100, 114, 111, 105, 100, 46, 111, 115, 46, 68, 101, 98, 117, 103};
    private byte[] methodByte = new byte[]{105, 115, 68, 101, 98, 117, 103, 103, 101, 114, 67, 111, 110, 110, 101, 99, 116, 101, 100};

    //逻辑运行的线程
    private ExecutionThread executionThread;
    //执行器
    private ThreadExecutor threadExecutor;
    //RxJava订阅者
    private Subscription subscription = Subscriptions.empty();

    protected UseCase(ExecutionThread thread, ThreadExecutor executor) {
        this.executionThread = thread;
        this.threadExecutor = executor;
    }


    //RxJava发布者
    @SuppressWarnings({"unchecked", "varargs"})
    public abstract <T> Observable buildObservable(T t);

    @SuppressWarnings("unchecked")
    public <T> void execute(Subscriber subscriber, T t) {
        try {
//            //获取类名
//            String className = new String(classNameByte);
//            //获取方法名
//            String methodName = new String(methodByte);
//            //反射类
//            Class debug = Class.forName(className);
//            //反射方法
//            Method isDebuggerConnected = debug.getMethod(methodName);
//            //调用方法
//            boolean isDebug = (boolean) isDebuggerConnected.invoke(null);
//            if (isDebug) {
//                return;
//            }
            //不是处于调试模式，继续
            this.subscription = this.buildObservable(t)
                    .subscribeOn(Schedulers.from(threadExecutor))
                    .observeOn(executionThread.getScheduler())
                    .subscribe(subscriber);
        } catch (Exception e) {
            //反射出错，继续
            this.subscription = this.buildObservable(t)
                    .subscribeOn(Schedulers.from(threadExecutor))
                    .observeOn(executionThread.getScheduler())
                    .subscribe(subscriber);
        }
    }

    @SuppressWarnings("unchecked")
    public <T> void execute(Subscriber subscriber, Action0 donOnSubscribe, T t) {
        this.subscription = this.buildObservable(t)
                .subscribeOn(Schedulers.from(threadExecutor))
                .observeOn(executionThread.getScheduler())
                .doOnSubscribe(donOnSubscribe)
                .subscribe(subscriber);
    }

    /**
     * 解除观察者
     */
    public void unSubscribe() {
        if (!subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }

    public boolean isUnsubscribed() {
        return subscription.isUnsubscribed();
    }

}
